package com.suos.core;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.system.HostInfo;
import cn.hutool.system.JvmInfo;
import cn.hutool.system.OsInfo;
import cn.hutool.system.SystemUtil;
import cn.hutool.system.oshi.CpuInfo;
import cn.hutool.system.oshi.OshiUtil;
import com.suos.entity.*;
import com.suos.utils.ChangeSizeUtil;
import org.springframework.beans.factory.annotation.Value;
import oshi.SystemInfo;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.FileSystem;
import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem;

import java.util.LinkedList;
import java.util.List;

/**
 * SugarOshi 信息获取
 *
 * @author : MisShi
 * @date: 2021-10-21 15:03:03
 */

public class SugarOshi {


    @Value("${sugar.oshi.unbid:''}")
    private String unbid;

    @Value("${sugar.oshi.wait-second:1000}")
    private int waitSecond;


    /**
     * 获取系统信息
     *
     * @return 服务器信息
     */
    public SysInfoMsg getSysInfo() {
        SysInfoMsg sysInfo = new SysInfoMsg();
        sysInfo.setUnbid(unbid);
        SystemInfo systemInfo = new SystemInfo();
        HardwareAbstractionLayer hardware = systemInfo.getHardware();
        sysInfo.setJvmMsg(getJvmInfo());
        sysInfo.setOsMsg(getOsInfo(systemInfo.getOperatingSystem()));
        sysInfo.setCpuMsg(getCpuInfo());
        sysInfo.setMemoryMsg(getMemoryInfo(hardware.getMemory()));
        sysInfo.setDisks(getDisksInfo(systemInfo.getOperatingSystem()));
        return sysInfo;
    }


    /**
     * 设置 JVM 信息
     */
    private JvmMsg getJvmInfo() {
        JvmMsg jvmMsg = new JvmMsg();
        JvmInfo jvmInfo = SystemUtil.getJvmInfo();
        Runtime runtime = Runtime.getRuntime();
        jvmMsg.setName(jvmInfo.getName());
        jvmMsg.setVersion(SystemUtil.getJvmSpecInfo().getVersion());
        jvmMsg.setDetailVersion(jvmInfo.getVersion());
        jvmMsg.setVendor(jvmInfo.getVendor());
        jvmMsg.setHomeDir(SystemUtil.getJavaRuntimeInfo().getHomeDir());
        jvmMsg.setTotalOcMem(ChangeSizeUtil.jcmSize(runtime.totalMemory()));
        jvmMsg.setMaxAvaMem(ChangeSizeUtil.jcmSize(runtime.maxMemory()));
        jvmMsg.setFreeMem(ChangeSizeUtil.jcmSize(runtime.freeMemory()));
        return jvmMsg;
    }

    /**
     * 设置 OS 信息
     *
     * @param operatingSystem 操作系统
     */
    private OsMsg getOsInfo(OperatingSystem operatingSystem) {
        OsMsg osMsg = new OsMsg();
        HostInfo hostInfo = SystemUtil.getHostInfo();
        OsInfo osInfo = SystemUtil.getOsInfo();
        osMsg.setOsName(operatingSystem.getFamily() + " " + operatingSystem.getVersionInfo().getVersion());
        osMsg.setOsArch(osInfo.getArch());
        osMsg.setOsBitness(operatingSystem.getBitness());
        osMsg.setOsVersion(operatingSystem.getVersionInfo().toString());
        osMsg.setOsVendor(operatingSystem.getManufacturer());
        osMsg.setHostName(hostInfo.getName());
        osMsg.setHostAddress(hostInfo.getAddress());
        //@TODO 计算不准
        //osMsg.setOsBootTime(DateUtil.format(DateUtil.date(operatingSystem.getSystemBootTime() * 1000L), "yyyy年MM月dd日 HH时mm分ss秒"));
        //osMsg.setOsUptime(DateUtil.formatBetween(operatingSystem.getSystemUptime() /1000L));
        return osMsg;
    }

    /**
     * 设置 CPU 信息
     */
    private CpuMsg getCpuInfo() {
        CpuMsg cpuMsg = new CpuMsg();
        CpuInfo cpuInfo = OshiUtil.getCpuInfo(waitSecond);
        cpuMsg.setCpuNum(cpuInfo.getCpuNum());
        cpuMsg.setCpuModel(cpuInfo.getCpuModel());
        cpuMsg.setToTal(cpuInfo.getToTal() + "%");
        cpuMsg.setSys(cpuInfo.getSys() + "%");
        cpuMsg.setUsed(cpuInfo.getUsed() + "%");
        cpuMsg.setFree(cpuInfo.getFree() + "%");
        cpuMsg.setWait(cpuInfo.getWait() + "%");
        return cpuMsg;
    }

    /**
     * 设置 MEMORY 信息
     */
    private MemoryMsg getMemoryInfo(GlobalMemory globalMemory) {
        MemoryMsg memoryMsg = new MemoryMsg();
        memoryMsg.setTotalMem(ChangeSizeUtil.jcmSize(globalMemory.getTotal()));
        memoryMsg.setUsedMem(ChangeSizeUtil.jcmSize(globalMemory.getTotal() - globalMemory.getAvailable()));
        memoryMsg.setFreeMem(ChangeSizeUtil.jcmSize(globalMemory.getAvailable()));
        return memoryMsg;
    }

    /**
     * 设置 DISK 信息
     */
    private List<DiskMsg> getDisksInfo(OperatingSystem operatingSystem) {
        List<DiskMsg> diskMsgs = new LinkedList<>();
        FileSystem fileSystem = operatingSystem.getFileSystem();
        List<OSFileStore> fsArray = fileSystem.getFileStores();
        DiskMsg diskMsg;
        for (OSFileStore fs : fsArray) {
            long free = fs.getUsableSpace();
            long total = fs.getTotalSpace();
            long used = total - free;
            diskMsg = new DiskMsg();
            diskMsg.setDirName(fs.getLabel());
            diskMsg.setSysTypeName(fs.getType());
            diskMsg.setTypeName(fs.getName());
            diskMsg.setTotal(ChangeSizeUtil.diskSize(total));
            diskMsg.setFree(ChangeSizeUtil.diskSize(free));
            diskMsg.setUsed(ChangeSizeUtil.diskSize(used));
            if (total != 0) {
                diskMsg.setUsage(NumberUtil.decimalFormat("#.##%", NumberUtil.div(used, total)));
            }
            diskMsgs.add(diskMsg);
        }
        return diskMsgs;
    }

    /**
     * 设置 PROJECT 信息
     */
    private Project getProjectInfo() {
        return new Project();
    }
}
